package com.groupa.project1.chat;


import com.groupa.project1.chat.interfaces.GenericMessage;
import com.groupa.project1.chat.interfaces.InstantMessage;
import com.groupa.project1.chat.interfaces.Listener;
import com.groupa.project1.chat.SearchProfileMessage;
import com.groupa.project1.chat.SearchResultMessage;
import com.groupa.project1.chat.UserContentMessage;
import com.groupa.project1.chat.interfaces.*;
import com.groupa.project1.database.DBActionClass;
import com.groupa.project1.database.DBManagerClass;
import com.groupa.project1.database.PhotoClass;
import com.groupa.project1.database.interfaces.DBActionResult;
import com.groupa.project1.database.interfaces.DBManager;
import com.groupa.project1.database.interfaces.Photo;
import com.groupa.project1.database.interfaces.XmlDbDataSource;
import com.groupa.project1.swing.editorsMenu;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Message;
/**
 *
 * @author groupA
 */
public class ListenerClass implements Listener, PacketListener{
    /*Implementa al patron observer. Cuando llega un mensage se invoca a una clase*/
    
    MultiUserChat chat;
    XMPPConnection con;
    InstantMessage msn;
    Logger log;
    DBManager manager;
    private static editorsMenu M;
    private static Properties Prop;
 
    ListenerClass(MultiUserChat chat, XMPPConnection con, InstantMessage msn, Logger log) {
         
        this.chat = chat;
        this.con = con;
        this.msn = msn;  
        this.log = log;
    }
    public void processPacket(Packet packet){
          
        
           if(packet instanceof Message){
  
               Message MSG = (Message) packet;  
               GenericMessage GM = (GenericMessage) MSG.getProperty("generic");
               String destination = GM.getOrigin();
               String origin = GM.getDestination();
               Object Obj = GM.getObj();
               ToolsClass Tools = new ToolsClass(log);
        
               Prop = InstantMessageClass.getPropertiesStatic(); 
 
               if(Obj instanceof UserContentMessage){
                 
                   log.info("Ha llegado un mensaje desde " + origin); 
                   log.info(" de tipo userContent."); 
                  
                   msn.setstatusUC();         
                   /* Obtenemos el objeto recibido*/
                   UserContentMessage UC = (UserContentMessage)Obj;
                   PhotoClass P = UC.getPhoto();
                   log.info("Path UC "+UC.getPath());  
                    String path = Prop.getProperty("GetPhoto/path")+ UC.getPath();
                   File fotoFinal = new File(path);
                   if(fotoFinal.exists()){
                        log.info("Foto obtenida");     
                        String name = fotoFinal.getName();
                        log.info("Creando contentClass");
                        ContentClass C = new ContentClass(Tools.toByteArray(fotoFinal),P);
                        C.setIsThumbnail(false);
                        SearchResultMessage SR = new SearchResultMessage();
                        SR.addContent(name,C);
                        SR.setIsPhoto(true);
                        log.info("Photo attached");  

                            GenericMessageClass GMC = new GenericMessageClass(origin,destination,SR);
                            /*Enviamos el mensaje*/
                            try{

                                    if(msn.send(GMC) == true){
                                    log.info("Generic message con SR enviado");
                                    }

                            } catch (Exception ex) {
                                    ex.printStackTrace();
                            }
                   }
                }
                if(Obj instanceof SearchProfileMessage){
                   
                    log.info("Ha llegado un mensaje desde " + origin); 
                    log.info(" de tipo searchProfile.");    
                    
                    msn.setstatusSp();
                    /* Obtenemos el objeto recibido*/
                    SearchProfileMessage SP= (SearchProfileMessage) Obj; 
                    String propertie = SP.getPropertie();
                    Object[] keywords = SP.getKeywords();
                    log.info("Propiedad: "+ propertie);  
                    /*Interaccion con la base de datos*/
                    manager = DBManagerClass.GetInstance();              
                    /*Creamos un objeto de tipo accion*/
                    DBActionClass DBact = new DBActionClass(propertie, keywords);
                    /*Establecemos la accion a realizar*/
                    DBActionResult DBres = manager.execute(DBact);
                    /*Obtenemos la lista de resultados*/
                    List L = DBres.getResult();
                    log.info("Lista de resultados obtenida: "); 
                    
                    DescriptionContent DC;
                    ContentClass C;
                    PhotoClass P;
                    String path;
                    String name;
                    SearchResultMessage SR = new SearchResultMessage();
                    
                    Iterator<Object> iterator = L.iterator();
                    
                    while (iterator.hasNext()) {
                         
                        P = (PhotoClass)iterator.next();
                        /* Obtenemos la foto y la convertimos en array de bits*/
                        log.info("Path: " + P.getPath()); 
                        
                        path = Prop.getProperty("GetPhoto/path")+ P.getPath();
                        log.info("Path foto: " + path);
       
                        File photo = new File(path);
                       
                        if(photo.exists()){
                        
                        name = photo.getName();
                        
                        
                        String thumbnailPath = Prop.getProperty("StoreThumbnail/path") + name;
                        /*Pasamos a thumbnail*/
                        try {
                           log.info("Thumbnail creada " + thumbnailPath);
                           Tools.createThumbnail(path, thumbnailPath, 100, 100);
                        } catch (Exception ex) {
                            Logger.getLogger(ListenerClass.class.getName()).log(Level.SEVERE, null, ex);
                            log.info("Error al crear la thumbnail");
                        }
                       
                        log.info("Thumbnail obtenida");
                        File thumbnail = new File(thumbnailPath);
                        name = thumbnail.getName();
                        
                        log.info("Creando contentClass");
                        C = new ContentClass(Tools.toByteArray(thumbnail),P);
                        C.setIsThumbnail(true);
                        
                        
                        SR.addContent(name,C);
                        SR.setIsPhoto(false);
                        log.info("Thumbnail attached");
                        
                        }
                        
                    }

                    GenericMessageClass GMC = new GenericMessageClass(origin,destination,SR);
                    /*Enviamos el mensaje*/
                    try{

                            if(msn.send(GMC) == true){
                            log.info("Generic message con SR enviado a " + GMC.getDestination());
                            }

                    } catch (Exception ex) {
                            ex.printStackTrace();
                    }
                    
                    
                    
                }
                if(Obj instanceof SearchResultMessage){
                    
                    log.info("Ha llegado un mensaje desde " + origin); 
                     
                    SearchResultMessage SR = (SearchResultMessage) Obj;
                    msn.setstatusSR();
                    SR.setOrigin(GM.getOrigin());
                    log.info(" de tipo searchResult.");
   
                    HashMap<String, Content> results =  SR.getContent();
                    log.info("Contenido extraido");
                   

                    String name = "";
         
                    Content C;
                    File imageFile;
                    Iterator itr = results.keySet().iterator();
                  
                    while(itr.hasNext()) {
                         log.info("entra en el while");
                         name = (String) itr.next();
                         C = (ContentClass)results.get(name);
                         
                        if(C.isThumbnail()){
                             log.info("Thumbnail recibida, cargando thumbnail...(mostrar thumbnail)");
                             imageFile = Tools.toPhoto(Prop.getProperty("StoreThumbnail/path") + name, C.getArray());
                             log.info("Guardada con nombre "+ Prop.getProperty("StoreThumbnail/path") + name);
                             /*Guardamos en una lista de thumbnails que mostraremos en el panel*/
                             
                        }
                        if(C.isThumbnail() == false){
                             log.info("Foto recibida, cargando foto...(mostrar foto)");
                             imageFile = Tools.toPhoto(Prop.getProperty("StorePhoto/path") + name, C.getArray());
                             log.info("Foto guardada con nombre "+ Prop.getProperty("StorePhoto/path") + name);
                        }
                        log.info("sale del while");
                     }
                    M =  editorsMenu.getEditorsMenu();
                    M.setSearchResult(SR);
                    log.info("SR enviado al menu");
                   

                }
          }
     
    }   
}